package v1

import (
	"encoding/json"
	"github.com/gin-gonic/gin"
	"github.com/shopspring/decimal"
	"maya-service/model/po"
	"maya-service/server/web/middleware"
	"maya-service/store/redis"
	"maya-service/utils"
	"maya-service/utils/request"
)

var Rank = &rank{}

func init() {
	RegisterRouter(Rank)
}

type rank struct{}

// Init
func (a *rank) Init(r *gin.RouterGroup) {
	g := r.Group("/rank", middleware.Auth())
	{
		// 登录
		g.POST("/list", a.rankList)
		g.POST("/aiConsultRank", a.aiConsultRank)

	}
}

// aiConsultRank 咨询排行榜
func (a *rank) aiConsultRank(c *gin.Context) {
	var (
		in  = &po.RankReq{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		c.Error(err)
		return
	}

	// 排行帮数据
	var userRankList []*po.UserData
	rankList, err := redis.GetLeaderBoardInstance().GetTopUsers(c.Request.Context(), "quanxi:ai_consult", int(in.TopNum))
	if err != nil {
		utils.ResponseOk(c, &po.RankRsp{List: userRankList})
		return
	}

	var userIds []string
	for i := 0; i < len(rankList); i++ {
		userIds = append(userIds, rankList[i].UserID)
	}

	var userId string
	if in.UserId == "" {
		userId, _ = request.GetUserId(c.Request.Context())
		if userId != "" {
			userIds = append(userIds, userId)
		}
	} else {
		userIds = append(userIds, in.UserId)
		userId = in.UserId
	}

	result, err := redis.KV.HMGet(c.Request.Context(), "quanxi:user_info", userIds...).Result()
	if err != nil {
		utils.ResponseOk(c, &po.RankRsp{List: userRankList})
		return
	}

	userMap := make(map[string]*request.UserData)
	for i := 0; i < len(userIds); i++ {
		userData := &request.UserData{}
		userMap[userIds[i]] = userData
		v, ok := result[i].(string)
		if !ok {
			continue
		}
		err = json.Unmarshal([]byte(v), userData)
		if err != nil {
			continue
		}
	}

	for i := 0; i < len(rankList); i++ {
		v1 := rankList[i].Score.Mul(decimal.NewFromInt32(1000000))
		v2 := rankList[i].Score.Round(0).Mul(decimal.NewFromInt32(1000000))
		data := &po.UserData{
			No:           i + 1,
			StaticsCount: int(v1.Sub(v2).IntPart()),
			TotalScore:   int(rankList[i].Score.Round(0).IntPart()),
		}
		if userInfo, ok := userMap[rankList[i].UserID]; ok {
			data.NickName = userInfo.UserName
			data.Avatar = userInfo.AvatarUrl
		}
		userRankList = append(userRankList, data)
	}

	out := &po.RankRsp{
		List:     userRankList,
		SelfRank: &po.UserData{},
	}
	// 自己排行信息
	if userId != "" {
		userScore, _ := redis.GetLeaderBoardInstance().GetUserScore(c.Request.Context(), "quanxi:ai_consult", userId)
		if userScore >= 0 {
			userRank, _ := redis.GetLeaderBoardInstance().GetUserRank(c.Request.Context(), "quanxi:ai_consult", userId)
			out.SelfRank = &po.UserData{
				No:           int(userRank),
				StaticsCount: int(userScore),
				TotalScore:   int(decimal.NewFromFloat32(userScore).Sub(decimal.NewFromInt(int64(userScore))).Mul(decimal.NewFromInt32(1000000)).IntPart()),
			}

			if userInfo, ok := userMap[userId]; ok {
				out.SelfRank.NickName = userInfo.UserName
				out.SelfRank.Avatar = userInfo.AvatarUrl
			}
		}
	}

	utils.ResponseOk(c, out)
}

// Rank 登录
func (a *rank) rankList(c *gin.Context) {
	var (
		in  = &po.RankReq{}
		err error
	)

	if err = c.ShouldBindJSON(in); err != nil {
		c.Error(err)
		return
	}

	// 排行帮数据
	var userRankList []*po.UserData
	rankList, err := redis.GetLeaderBoardInstance().GetTopUsers(c.Request.Context(), "quanxi:question", int(in.TopNum))
	if err != nil {
		utils.ResponseOk(c, &po.RankRsp{List: userRankList})
		return
	}

	var userIds []string
	for i := 0; i < len(rankList); i++ {
		userIds = append(userIds, rankList[i].UserID)
	}

	result, err := redis.KV.HMGet(c.Request.Context(), "quanxi:user_info", userIds...).Result()
	if err != nil {
		utils.ResponseOk(c, &po.RankRsp{List: userRankList})
		return
	}

	userMap := make(map[string]*request.UserData)
	for i := 0; i < len(userIds); i++ {
		userData := &request.UserData{}
		err = json.Unmarshal([]byte(result[i].(string)), userData)
		if err != nil {
			continue
		}
		userMap[userIds[i]] = userData
	}

	for i := 0; i < len(rankList); i++ {
		data := &po.UserData{
			No: i + 1,
			//AnswerCount: int(rankList[i].Score),
			//AvgScore:   int((rankList[i].Score - float64(int(rankList[i].Score))) * 1000),
			TotalScore: int(rankList[i].Score.IntPart()),
		}

		if userInfo, ok := userMap[rankList[i].UserID]; ok {
			data.NickName = userInfo.UserName
			data.Avatar = userInfo.AvatarUrl
		}
		userRankList = append(userRankList, data)
	}
	utils.ResponseOk(c, &po.RankRsp{List: userRankList})
}
